package com.bing.bingPro.service.impl;

import cn.hutool.core.text.CharSequenceUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bing.bingPro.controller.dto.ZdBasicOrderDto;
import com.bing.bingPro.controller.vo.ZdSupportOrderVo;
import com.bing.bingPro.entity.DZoneInfo;
import com.bing.bingPro.entity.ZdSupportOrder;
import com.bing.bingPro.mapper.DZoneInfoMapper;
import com.bing.bingPro.mapper.ZdSupportOrderMapper;
import com.bing.bingPro.service.ZdSupportOrderService;
import com.bing.bingPro.util.ProvinceUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author wangqilong
 * @description 针对表【zd_support_order(OLAP)】的数据库操作Service实现
 * @createDate
 */
@Service
public class ZdSupportOrderServiceImpl extends ServiceImpl<ZdSupportOrderMapper, ZdSupportOrder>
        implements ZdSupportOrderService {

    @Resource
    private DZoneInfoMapper dZoneInfoMapper;

    @Override
    public List<ZdSupportOrderVo> zdSupportList(ZdBasicOrderDto zdBasicOrderDto) {
        String time = zdBasicOrderDto.getTime();
        String province = ProvinceUtil.getKeyProvince(zdBasicOrderDto.getProvince());

        List<ZdSupportOrder> zdSupportOrders = baseMapper.selectList(Wrappers.lambdaQuery(ZdSupportOrder.class)
                .eq(CharSequenceUtil.isNotEmpty(zdBasicOrderDto.getProvince()), ZdSupportOrder::getProvinceCode, province)
                .eq(CharSequenceUtil.isNotEmpty(time), ZdSupportOrder::getDt, time));
        Map<Integer, DZoneInfo> regionInfoMap = getIntegerDZoneInfoMap(zdSupportOrders);

        List<Long> regionCodes = zdSupportOrders.stream()
                .filter(z -> CharSequenceUtil.isNotEmpty(z.getRegionCode()))
                .filter(z -> z.getRegionCode().length() < 9)
                .map(z -> Long.parseLong(z.getRegionCode()))
                .distinct()
                .collect(Collectors.toList());

        Map<Integer, DZoneInfo> zoneInfoMap;
        if (!regionCodes.isEmpty()) {
            List<DZoneInfo> regionInfos = dZoneInfoMapper.selectByZoneIds(regionCodes);
            zoneInfoMap = regionInfos.stream().collect(Collectors.toMap(DZoneInfo::getZoneId, Function.identity(), (existingValue, newValue) -> newValue));
        } else {
            zoneInfoMap = Collections.emptyMap();
        }

        return zdSupportOrders.stream().map(getSupportOrderZdSupportOrderVoFunction(regionInfoMap, zoneInfoMap)).collect(Collectors.toList());
    }

    private Function<ZdSupportOrder, ZdSupportOrderVo> getSupportOrderZdSupportOrderVoFunction(Map<Integer, DZoneInfo> regionInfoMap, Map<Integer, DZoneInfo> zoneInfoMap) {
        return zdSupportOrder -> {
            ZdSupportOrderVo vo = new ZdSupportOrderVo();
            BeanUtils.copyProperties(zdSupportOrder, vo);
            vo.setProvinceCode(ProvinceUtil.getProvince(zdSupportOrder.getProvinceCode()));
            if (CharSequenceUtil.isNotEmpty(zdSupportOrder.getCityCode()) && zdSupportOrder.getCityCode().matches("\\d+")) {
                Integer zoneId = Integer.parseInt(zdSupportOrder.getCityCode());
                DZoneInfo dZoneInfo = regionInfoMap.get(zoneId);
                vo.setCityCode(dZoneInfo != null ? dZoneInfo.getZoneName() : null);
            }
            if (CharSequenceUtil.isNotEmpty(zdSupportOrder.getRegionCode()) && zdSupportOrder.getRegionCode().matches("\\d+")) {
                Integer regionID = Integer.parseInt(zdSupportOrder.getRegionCode());
                DZoneInfo region = zoneInfoMap.get(regionID);
                vo.setRegionCode(region != null ? region.getZoneName() : null);
            }
            return vo;
        };
    }

    private Map<Integer, DZoneInfo> getIntegerDZoneInfoMap(List<ZdSupportOrder> zdSupportOrders) {
        List<Long> cityCodes = zdSupportOrders.stream()
                .filter(z -> CharSequenceUtil.isNotEmpty(z.getCityCode()))
                .map(z -> Long.parseLong(z.getCityCode()))
                .distinct()
                .collect(Collectors.toList());

        List<DZoneInfo> dZoneInfos = dZoneInfoMapper.selectByZoneIds(cityCodes);
        return dZoneInfos.stream().collect(Collectors.toMap(DZoneInfo::getZoneId, Function.identity(), (existingValue, newValue) -> newValue));
    }

    @Override
    public List<String> dateList() {
        return baseMapper.dateList();
    }

    @Override
    public List<String> getCountry() {
        List<String> country = baseMapper.getCountry();
        country.add(0, "全国");
        return country;
    }

    @SuppressWarnings("unchecked")
    @Override
    public IPage<ZdSupportOrderVo> zdSupportPageList(ZdBasicOrderDto zdBasicOrderDto) {
        IPage<ZdSupportOrderVo> voIPage = new Page<>();
        Page page = new Page(zdBasicOrderDto.getPageNum(), zdBasicOrderDto.getPageSize());
        String time = zdBasicOrderDto.getTime();
        String province = ProvinceUtil.getKeyProvince(zdBasicOrderDto.getProvince());

        IPage<ZdSupportOrder> zedPage = baseMapper.selectPage(page, Wrappers.lambdaQuery(ZdSupportOrder.class)
                .eq(CharSequenceUtil.isNotEmpty(zdBasicOrderDto.getProvince()), ZdSupportOrder::getProvinceCode, province)
                .eq(CharSequenceUtil.isNotEmpty(time), ZdSupportOrder::getDt, time));
        List<ZdSupportOrder> zeds = zedPage.getRecords();

        Map<Integer, DZoneInfo> cityInfoMap = getIntegerDZoneInfoMap(zeds);

        List<Long> regionCodes = zeds.stream()
                .filter(z -> CharSequenceUtil.isNotEmpty(z.getRegionCode()) && z.getRegionCode().matches("\\d+"))
                .map(z -> Long.parseLong(z.getRegionCode()))
                .distinct()
                .collect(Collectors.toList());

        Map<Integer, DZoneInfo> zoneInfoMap;
        if (!regionCodes.isEmpty()) {
            List<DZoneInfo> regionInfos = dZoneInfoMapper.selectByZoneIds(regionCodes);
            zoneInfoMap = regionInfos.stream().collect(Collectors.toMap(DZoneInfo::getZoneId, Function.identity(), (existingValue, newValue) -> newValue));
        } else {
            zoneInfoMap = Collections.emptyMap();
        }

        List<ZdSupportOrderVo> collect = zeds.stream().map(getSupportOrderZdSupportOrderVoFunction(cityInfoMap, zoneInfoMap)).collect(Collectors.toList());
        voIPage.setRecords(collect);
        voIPage.setTotal(zedPage.getTotal());
        voIPage.setPages(zedPage.getPages());
        voIPage.setCurrent(zedPage.getCurrent());
        voIPage.setSize(zedPage.getSize());
        return voIPage;
    }
}




